// $codepro.audit.disable obsoleteModifierUsage
/*
 * Copyright (c) 2011 Team A CS2340. All rights reserved.
 */

package edu.gatech.teama.doctorsoffice.server;

import java.util.List;
import java.util.Map;

import org.joda.time.LocalDateTime;

import edu.gatech.teama.doctorsoffice.model.Appointment;
import edu.gatech.teama.doctorsoffice.model.Patient;
import edu.gatech.teama.doctorsoffice.model.User;
import edu.gatech.teama.doctorsoffice.net.LoginResult;

/**
 * An interface of the data model used by the system's server.
 * Can be implemented using different storage backends
 * to allow for different means of data storage.
 * @author Team A
 * @version 1.0
 *
 */
public interface DataModel {

	/**
	 * Forces data to be saved to disk.
	 * May not be necessary for all <code>DataModel</code> implementations
	 */
	void saveToDisk();
	
	/**
	 * Force a reload of data from disk. Will overwrite data in memory.
	 */
	void forceLoadFromDisk();
	
	/**
	 * Add a new user.
	 * @param u <code>User</code> to add
	 * @param passwordHash password after being hashed
	 */
	void addUser(User u, String passwordHash);
	
	/**
	 * Delete existing user.
	 * @param username username of <code>User</code> to delete
	 * @return deleted <code>User</code>
	 */
	User deleteUser(String username);
	
	/**
	 * Store updated information on a <code>User</code>
	 * @param u <code>User</code> to update
	 */
	void updateUser(User u);
	
	/**
	 * Get an existing <code>User</code>
	 * @param username username of <code>User</code> to retrieve
	 * @return <code>User</code> corresponding to username
	 */
	User readUser(String username);
	
	/**
	 * Verify a user's password and log them into the server.
	 * @param username username of user to log in
	 * @param passwordHash hash of the user's password
	 * @return a <code>LoginResult</code> specifying the status of the login attempt
	 */
	LoginResult verifyPasswordHash(String username, String passwordHash);
	
	/**
	 * Lookup a <code>Patient</code> by their name.
	 * Creates a <code>List</code> of possible matches.
	 * For example, if last name "Smith" is searched for, a <code>List</code>
	 * of all Smiths will be returned.
	 * @param firstname first name of patient
	 * @param lastname last name of patient
	 * @return a <code>List</code> of possible matches
	 */
	List<Patient> lookupPatientByName(String firstname, String lastname);
	
	/**
	 * get users of certain type class
	 * @param typeClass
	 * @return list of users
	 */
	List<User> getUsersOfType(String typeClass);
	
	/**
	 * lookup appointment
	 * @param key
	 * @return appointment
	 */
	Appointment lookupAppointment(String key);
	
	/**
	 * update appointment
	 * @param appointment
	 */
	void updateAppointment(Appointment appointment);
	
	/**
	 * map for get appointment for date
	 * @param date
	 * @return appointments
	 */
	Map<String,Appointment> getAppointmentsForDate(String date);
	
	/**
	 * add appointment
	 * @param patient
	 * @param appointment
	 */
	void addAppointment(Patient patient, Appointment appointment);
	
	/**
	 * get appointment for user
	 * @param username
	 * @return appointment list
	 */
	public List<Appointment> getAppointmentsForUser(String username); //<!-- // $codepro.audit.disable -->
	
	/**
	 * get appointment times for date
	 * @param date
	 * @return appointment timess
	 */
	public List<LocalDateTime> getAppointmentTimesForDate(String date); //<!-- // $codepro.audit.disable -->
	
	public void changePassword(User user, String newPassword);
}
